classdef car < handle
    %car this class represents a car
    %   details
        
    properties (SetAccess = public)
        delta = 4
        position;       % On the road, in meters
        velocity = 0;   % Current velocity, in m/s        
        length;         % Length of the vehicle, in meters
        path;
        name;
        % IDM Constants ---------------------------------------
        dVelocity       % The desired velocity
        minSpace        % The minimum spacing between two cars
        dTimeHead       % Desired time-headway between two cars
        dAccel          % Desired Acceleration, in m/s^2
        decel           % Comfortable braking deceleration
    end
    
    methods        
        %Creates a car and gives value to all properties
        function c = car(Length, desiredVelocity, ... 
                minimalSpace, timeheadway, desiredAcceleration, ...
                Deceleration, name)
            % The car's initial position is handled by the road
            c.length = Length;
            c.dVelocity = desiredVelocity;
            c.minSpace = minimalSpace;
            c.dTimeHead = timeheadway;
            c.dAccel = desiredAcceleration;
            c.decel = Deceleration;
            c.name = name;
        end
        
        %makes the car drive, here IDM has to go
        function drive(c ,prevCar)
           acceleration = c.accelerate(prevCar);
           c.velocity = c.velocity + acceleration;
           c.position = c.position + c.velocity;
           
           display(sprintf('Speed: %f\nDistance traveled: %f\nVehicle: %s\n', c.velocity, c.position, c.name))
        end
        
        function acceleration = accelerate(c, prevCar)
            if ~isempty(prevCar)
                Sa = prevCar.position - c.position - prevCar.length;
                DVa = c.velocity - prevCar.velocity;
            else
                Sa = 100;
                DVa = c.velocity;
            end
            
            Sstar = c.minSpace + c.velocity * c.dTimeHead + ... 
                (c.velocity*DVa)/(2*sqrt(c.dAccel*c.decel));
            
            acceleration = c.dAccel*(1-(c.velocity/c.dVelocity)^c.delta ...
                - (Sstar/Sa)^2);            
        end
        
        %the car goes on a new road
        function turn(c,newRoad)
            c.road = newRoad;
            c.position = 0;
        end   
    end
end
